package com.waijiaojun.tpo.service.weixin;

import java.io.IOException;
import java.util.Calendar;
import java.util.Date;

import com.waijiaojun.tpo.utils.JsonUtil;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import com.waijiaojun.tpo.entity.weixin.WeixinAccessToken;
import com.waijiaojun.tpo.entity.weixin.WeixinAccessTokenLog;
import com.waijiaojun.tpo.entity.weixin.WeixinPublic;
import com.waijiaojun.tpo.exception.ServerException;
import com.waijiaojun.tpo.repository.weixin.WeixinAccessTokenDao;
import com.waijiaojun.tpo.repository.weixin.WeixinAccessTokenLogDao;
import com.waijiaojun.tpo.rest.dto.ReceiveAccessTokenDto;
import com.waijiaojun.tpo.utils.HttpUtil;

/**
 * @author Peter
 */
// Spring Service Bean的标识.
@Component
public class WeixinAccessTokenService {

    private static String ACCESS_TOKEN = null;
    private static Integer EXPIRES_IN = null;
    private static Date SEND_TIME = null;

    private static Logger logger = LoggerFactory.getLogger(WeixinAccessTokenService.class);

    @Autowired
    private WeixinConf weixinConf;

    @Autowired
    private WeixinPublicService weixinPublicService;


    @Autowired
    private WeixinAccessTokenDao weixinAccessTokenDao;

    @Autowired
    private WeixinAccessTokenLogDao weixinAccessTokenLogDao;

    public String getAccessToken()  {
        WeixinAccessToken weixinAccessToken = weixinAccessTokenDao.getByWeixinPublicId(weixinConf.getPublicId());
        if (weixinAccessToken == null) {
            // 数据库中没有AccessToken信息，从微信服务器获取AccessToken
            ReceiveAccessTokenDto dto = receiveAccessToken();
            weixinAccessToken = dtoToEntity(dto);
            WeixinAccessTokenLog log = dtoToEntityLog(dto);

            weixinAccessTokenDao.save(weixinAccessToken);
            weixinAccessTokenLogDao.save(log);
        } else {
            // 判断是否过期
            if (isExpires(weixinAccessToken)) {
                //过期，重新获取ticket
                Long id = weixinAccessToken.getId();
                ReceiveAccessTokenDto dto = receiveAccessToken();
                weixinAccessToken = dtoToEntity(dto);
                weixinAccessToken.setId(id);
                WeixinAccessTokenLog log = dtoToEntityLog(dto);
                weixinAccessTokenDao.update(weixinAccessToken);
                weixinAccessTokenLogDao.save(log);
            }
        }
        return weixinAccessToken.getAccessToken();
    }

    // 获取access_token
    public ReceiveAccessTokenDto receiveAccessToken() {
        WeixinPublic weixinPublic = weixinPublicService.getGlobleWeixinPublic();
        String url = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=" + weixinPublic.getAppId() + "&secret=" + weixinPublic.getAppSecret();

        String body = HttpUtil.httpGet(url);
        ReceiveAccessTokenDto bean = null;
        try {
            bean = JsonUtil.toObject(body, ReceiveAccessTokenDto.class);
        } catch (IOException e) {
            throw new ServerException("获取access_token失败：从微信服务器读取数据失败");
        }

        if (StringUtils.isNotBlank(bean.getErrcode())) {
            throw new ServerException(bean.getErrmsg());
        }

        EXPIRES_IN = Integer.valueOf(bean.getExpires_in());
        SEND_TIME = new Date();

        return bean;
    }

    private WeixinAccessToken dtoToEntity(ReceiveAccessTokenDto dto) {
        WeixinAccessToken token = new WeixinAccessToken();
        token.setAccessToken(dto.getAccess_token());
        token.setCreateDate(new Date());
        token.setExpiresIn(Long.parseLong(dto.getExpires_in()));
        token.setUpdateDate(new Date());
        token.setWeixinPublicId(weixinConf.getPublicId());
        return token;
    }

    private WeixinAccessTokenLog dtoToEntityLog(ReceiveAccessTokenDto dto) {
        WeixinAccessTokenLog tokenLog = new WeixinAccessTokenLog();

        if (StringUtils.isBlank(dto.getErrcode())) {
            tokenLog.setAccessToken(dto.getAccess_token());
            tokenLog.setExpiresIn(Long.parseLong(dto.getExpires_in()));
        } else {
            tokenLog.setErrcode(dto.getErrcode());
            tokenLog.setErrmsg(dto.getErrmsg());
        }

        tokenLog.setCreateDate(new Date());
        tokenLog.setWeixinPublicId(weixinConf.getPublicId());
        return tokenLog;
    }

    /**
     * 是否过期
     *
     * @return boolean true:过期，false:未过期
     */
    public boolean isExpires(WeixinAccessToken token) {
        boolean isExpires = false;

        Calendar sendedCal = Calendar.getInstance();//
        sendedCal.setTime(token.getUpdateDate());
        sendedCal.add(Calendar.SECOND, token.getExpiresIn().intValue() - 120);//提前2分钟过期

        Calendar nowCal = Calendar.getInstance();
        nowCal.setTime(new Date());

        System.out.println(sendedCal.getTime());
        System.out.println(nowCal.getTime());
        if (sendedCal.before(nowCal)) {
            isExpires = true;
        }

        return isExpires;
    }

}
